#include<stdio.h>
#include<stdlib.h>

#define MAXTREE 10
#define ElementType char
#define Tree int
#define Null -1
//小白专场

//给定两棵树T1，T2，若T1可以通过若干次左右孩子互换就变成T2，就说他们是同构的
//现给定两棵树，判断他们是否是同构的

//我的考虑是用层序遍历,但是这种情况如果有结点在同一层但是在不同子树上就不满足了，因此换个思路。
/* typedef struct TreeNode *BinTree;
struct TreeNode
{
    int Data;
    BinTree left;
    BinTree right;
}; */

//输入格式：输入给出2棵二叉树的信息
//先在一行给出该树的结点树，各结点从0开始依次编号
//随后第i行给出该节点存储的字母，其左孩子的编号，其右孩子的编号
//若孩子的结点为空，就输入'-'
//这种输入方法不需要要求输入的顺序一定是从上到下，是需要保证结点之间的连接关系就可以随意定输入顺序

/*
求解思路：
二叉树怎么表示？
怎么根据输入建立二叉树？
怎么判断是否同构？
*/

//采用结构数组来表示二叉树,left和right分别是左右孩子的编号，而不是指针
struct TreeNode
{//怎么判断根节点呢？可以看left和right中没有出现过的数！！！
    ElementType elem;//结点内存储的元素
    Tree left;
    Tree right;
} T1[MAXTREE], T2[MAXTREE];

Tree BuildTree(struct TreeNode T[]);//返回树的根结点编号
int Isomorphic(Tree root1, Tree root2);

int main()
{
    Tree R1, R2;
    //建二叉树1
    R1 = BuildTree(T1);
    //建二叉树2
    R2 = BuildTree(T2);
    //判断是否同构并且输出
    if(Isomorphic(R1,R2))
        printf("Yes!\n");
    else
        printf("No!\n");
    return 0;
}

Tree BuildTree(struct TreeNode T[])
{
    int Root,p;
    char cl, cr;
    int N;
    int check[MAXTREE];
    scanf("%d", &N);
    getchar();
    if(N > MAXTREE - 1)
        return Null;//防止数组溢出
    if(N)
    {
        for (int i = 0; i < N;i++)
        {
            check[i] = 0;//初始化check数组，用来标识下标为i的元素是否被指到过
        }
        for (int j = 0; j < N;j++)
        {
            scanf("%c %c %c", &T[j].elem, &cl, &cr);
            if(cl != '-')
            {
                T[j].left = cl - '0';
                check[T[j].left] = 1;//用1标记T[j].left已被指
            }
            else
                T[j].left = Null;
            if(cr != '-')
            {
                T[j].right = cr - '0';
                check[T[j].right] = 1;
            }
            else
                T[j].right = Null;
        }

        //开始寻根
        for (p = 0; p < N;p++)
        {
            if(check[p] == 0)
                break;
        }
        Root = p;
    }
    return Root;
}

int Isomorphic(Tree root1,Tree root2)
{
    if((root1 == Null) && (root2 == Null))
        return 1;
    if((root1 == Null && root2 != Null) || (root1 != Null && root2 == Null))
        return 0;
    if(T1[root1].elem != T2[root2].elem)
        return 0;
    if(T1[root1].left == Null && T2[root2].left == Null)
        return Isomorphic(T1[root1].right, T2[root2].right);
    if(T1[root1].right == Null && T2[root2].right == Null)
        return Isomorphic(T1[root1].left, T2[root2].left);
    
    if((T1[root1].left != Null && T2[root2].right != Null) && (T1[T1[root1].left].elem == T2[T2[root2].left].elem))
        return (Isomorphic(T1[root1].left, T2[root2].left) && Isomorphic(T1[root1].right, T2[root2].right));
    else
        return (Isomorphic(T1[root1].left, T2[root2].right) && Isomorphic(T1[root1].right, T2[root2].left));
}